interface Hash{
    //存放元素
    _storehouse: Array<Array<any>>;
    //初始长度
    size: number;
    //存放个数
    length: number;
    //获取key的值
    get(key: string): any;
}
class HashTable implements Hash{
    _storehouse: Array<Array<any>> = [];
    size=7;
    length=0;
    constructor(...value: Array<Array<any>>) {
        for (let index = 0; index < value.length;index++){
            this.put(value[index][0], value[index][1])
        }
    }
    private hashCode(key:string):number {
        let code: number = 0;
        for (let index = 0; index < key.length;index++){
            code=37*code+key.charCodeAt(index)
        }
        let index = code % this.size
        return index
    };
    put(key: string, value: any): any {
        let index = this.hashCode(key);
        let box: Array<any> = this._storehouse[index];
        if (Array.isArray(box)) {
            for (let i = 0; i < box.length; i++) {
                if (box[i][0] == key) {
                    box[i][1] = value
                    return value
                }
            }
        } else {
            this._storehouse[index] = [];
        }
        this._storehouse[index].push([key, value])
        this.length++;
        if (this.length/this.size>0.75) {
            this.dilatation()
        }
        return value
    };
    get(key: string): any {
        let index: number = this.hashCode(key);
        if (this._storehouse[index]) {
            for (let i = 0; i < this._storehouse[index].length; i++) {
                if (this._storehouse[index][i][0] == key) {
                    return this._storehouse[index][i][1]
                }
            }
        }
        return undefined
    };
    remove(key:string):boolean {
        let index: number = this.hashCode(key);
        if (this._storehouse[index]) {
            for (let i = 0; i < this._storehouse[index].length; i++) {
                if (this._storehouse[index][i][0] == key) {
                    this._storehouse[index].splice(i, 1)
                    this.length--
                    return true
                }
            }
        }
        return false
    }
    //判断是否是质数
    private isPrime(num:number): boolean {
        let root: number = Math.ceil(Math.sqrt(5));
        
        for (let i = 2; i <= root; i++){
            if (num % i == 0) {
                return false
            }
        }
        return true
    }
    //扩容或者缩容
    private dilatation(): void {
        //初始化
        let data: Array<any> = this._storehouse;
        this._storehouse = [];
        this.length = 0;
        this.size *= 2;
        while (this.isPrime(this.size)==false) {
            this.size++
        }
        for (let index = 0; index < data.length;index++){
            if (Array.isArray(data[index])) {
                for (let i = 0; i < data[index].length;i++){
                    this.put(data[index][i][0], data[index][i][1])
                }
            }
        }
    }
}
export default HashTable
